package Game;

import java.util.Random;

public class Field {
	// CONSTANTS
	
	// ATTRIBUTES
	Cell[][] matrix;
	
	// METHODS
	
	/**
	 * Constructs a Field with the specified width and height.
	 * @param _width Field's width
	 * @param _height Field's height
	 */
	public Field(int width, int height) {
		matrix = new Cell[height][];
		for (int x = 0; x < matrix.length; x++) {
			matrix[x] = new Cell[width];
			for (int y = 0; y < matrix[x].length; y++) {
				matrix[x][y] = new Cell(x, y);
			}
		}
	}
	
	/**
	 * Creates a randomized Field.
	 * @param width Width of the field.
	 * @param height Height of the field.
	 * @param percent Probability that cells are occupiable.
	 * @param avgAltitude Average height of every cell.
	 * @param stdevAltitude Standard deviation of height of every cell.
	 * @return Random Field
	 */
	public static Field randomField(int width, int height, int percent, int avgAltitude, int stdevAltitude) {
		Field random = new Field(width, height);
		Random rand = new Random();
		
		for (Cell[] lines: random.matrix) {
			for (Cell cell: lines) {
				if (rand.nextInt(101) > percent) {
					cell.altitude = 0;
				} else {
					do {
						cell.altitude = avgAltitude + (int)Math.round(rand.nextGaussian()*stdevAltitude);
					} while (cell.altitude <= 0);
				}
			}
		}
		
		return random;
	}
	
	/**
	 * Returns Field's width.
	 * @return Field's width
	 */
	public int width() {
		return matrix[0].length;
	}
	
	/**
	 * Return Field's height.
	 * @return Field's height
	 */
	public int height() {
		return matrix.length;
	}
	
	/**
	 * Return Field's area, i.e. its width times its height.
	 * @return Field's area
	 */
	public int area() {
		return width()*height();
	}
	
	/**
	 * Finds the maximum altitude of all cells.
	 * @return Maximum altitude of all cells.
	 */
	private int maxAltitude() {
		int max = 0;
		
		for (Cell[] lines: matrix) {
			for (Cell cell: lines) {
				if (cell.altitude > max)
					max = cell.altitude;
			}
		}
		
		return max;
	}
	
	/**
	 * Returns the number of cells which are occupiable.
	 * @return Number of cells which are occupiable.
	 */
	private int numOccupiable() {
		int num = 0;
		
		for (Cell[] lines: matrix) {
			for (Cell cell: lines) {
				if (cell.isOccupiable())
					num++;
			}
		}
		
		return num;
	}
	
	/**
	 * Returns the number of cells which are unoccupiable.
	 * @return Number of cells which are unoccupiable.
	 */
	private int numUnoccupiable() {
		return width()*height() - numOccupiable();
	}
	
	@Override
	public String toString() {
		String s = "";
		
		int maxDigit = (maxAltitude() + "").length();
		
		for (Cell[] lines: matrix) {
			for (Cell cell: lines) {
				s += cell.altitude + new String(new char[maxDigit]).replace("\n", " ");
			}
			s += "\n";
		}
		
		return s;
	}
	
	public static void main(String[] args) {
		Field field = randomField(10, 10, 80, 5, 3);
		System.out.println(field);
	}
}
